package com.springmvc.shangguigu.controller;

import com.springmvc.shangguigu.entities.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Writer;

/**
 * SpringMvcController--SpringMVC-test
 *
 * @author: Jovi
 * @createTime: 2018-08-24 15:56
 **/
@Controller
@RequestMapping("/springmvc")
public class SpringMvcRequestController {

    private static final String SUCCESS = "shangguigu/success";

    /**
     * 1.@RequestMapping 除了修饰方法，还可以来修饰类
     * 2.类定义处：提供初步的请求信息。相对于web应用的根目录
     * 方法处：提供进一步的细分映射信息。
     * 相对于类定义处的URL。若类定义处未标注@RequestMapping，则方法标记处的URL相对于WEB应用的根目录
     *
     * @return
     */
    @RequestMapping(value = "/testRequestMapping")
    public String testReqestMapping() {
        System.out.println("testReqestMapping");
        return SUCCESS;
    }

    /**
     * 使用method 属性来指定请求方式
     *
     * @return
     */
    @RequestMapping(value = "/testMethod", method = RequestMethod.POST)
    public String testMethod() {
        System.out.println("testMethod");
        return "SUCCESS";
    }

    /**
     * 使用params和headers 来更加精确的映射请求，支持简单的表达式
     * <p>
     * param1: 表示请求必须包含名为 param1 的请求参数
     * !param1: 表示请求不能包含名为 param1 的请求参数
     * param1 != value1: 表示请求包含名为 param1 的请求参数，但其– 值
     * 不能为 value1
     * {“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 –
     * 的两个请求参数，且 param1 参数的值必须为 value1
     *
     * @return
     */
    @RequestMapping(value = "/testParamsAndHeaders",
            headers = {"Accept-Language=zh-CN,zh;q=0.9,en;q=0.8"},
            params = {"username", "age!=10"})
    public String testParamsAndHeaders() {
        System.out.println("testParamsAndHeaders");
        return SUCCESS;
    }

    /**
     * @return
     * @RequestMapping 还支持 Ant 风格的 URL
     * /user/{**}/createUser 匹配 /user/aaa/bbb/createUser
     * /user/{*}/createUser 匹配 /user/aaa/createUser
     * /user/createUser?? 匹配  /user/createUseraa
     */
    @RequestMapping("/testAntPath/*/abc")
    public String testAntPath() {
        System.out.println("testAntPath");
        return SUCCESS;

    }

    /**
     * @param id
     * @return
     * @PathVariable 映射 URL 绑定的占位符
     */
    @RequestMapping("/testPathVariable/{name}")
    public String testPathVariable(@PathVariable("name") Integer id) {
        System.out.println("testPathVariable:" + id);
        return SUCCESS;
    }

    /**
     * Rest 风格的URL.
     * 以CRUD为例：
     * 新增：/order POST
     * 修改：/order/1 PUT update?id=1
     * 获取：/order/1 GET get?id=1
     * 删除: /order/1 DELETE delete?id=1
     * <p>
     * 需要配置HiddenHttpMethodFilter
     * 需要发送POST请求
     * 需要在发送POST请求时携带一个name="_method"的隐藏域，值为DELETE或PUT
     * <p>
     * 在SpringMvc的目标中如得到ID呢？
     * 使用@PathVariable注解
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
    public String testRest(@PathVariable Integer id) {
        System.out.println("testRest GET:" + id);
        return SUCCESS;
    }

    @RequestMapping(value = "/testRest", method = RequestMethod.POST)
    public String testRest() {
        System.out.println("testRest POST");
        return SUCCESS;
    }

    @RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE)
    public String testRestDelete(@PathVariable Integer id) {
        System.out.println("testRest DELETE:" + id);
        return SUCCESS;
    }

    @RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
    public String testRestPut(@PathVariable Integer id) {
        System.out.println("testRest PUT:" + id);
        return SUCCESS;
    }

    /**
     * @RequestParam 来映射请求参数
     * value 即为请求参数的参数名
     * required 该参数是否必须
     * defaultValue 请求参数的默认值
     * @param un
     * @param age
     * @return
     */
    @RequestMapping(value = "/testRequestParam")
    public String testRequestParam(@RequestParam(value = "username") String un,
                                   @RequestParam(value = "age", required = false, defaultValue = "0") int age) {
        System.out.println("testRequestParam,username:" + un + ",age:" + age);
        return SUCCESS;
    }


    /**
     * 用法同@RequestParam
     * 映射请求头信息
     * @param al
     * @return
     */
    @RequestMapping("/testRequestHeader")
    public String testRequestHeader(@RequestHeader(value = "Accept-Language")String al) {
        System.out.println("testRequestHeader,Accept-Language:"+al);
        return  SUCCESS;
    }

    /**
     * @CookieValue ：映射一个Cookie值，属性同@RequestParam
     * @param sessionId
     * @return
     */
    @RequestMapping("/testCookieValue")
    public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) {

        System.out.println("testCookieValue,JSESSIONID:" + sessionId);
        return SUCCESS;
    }

    /**
     * Spring MVC 会按• 请求参数名和 POJO 属性名进行自动匹
     * 配，自动为该对象填充属性值。支持级联属性。
     * 如：dept.deptId、dept.address.tel 等
     * @param user
     * @return
     */
    @RequestMapping("/testPojo")
    public String testPojo(User user) {
        System.out.println("testPojo"+user);
        return SUCCESS;
    }

    @RequestMapping("/testServlet")
    public void testServlet(HttpServletRequest request, HttpServletResponse response, Writer out) {
        System.out.println("testServlet:"+request+response);
        try {
            out.write("hello");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
